package search;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import mapapp.ConnectToDatabase;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Cookie
 */
public class Bidirectional {

    final int MAX = 1000; // maximum number of connections
// This array holds the flight information.
    ArrayList<TraseuInfo> trasee =new ArrayList<TraseuInfo>();
    //TraseuInfo trasee[] = new TraseuInfo[MAX];
    //int numTrasee = 0; // number of entries in flight array

    public Stack btStackForward = new Stack(); // backtrack stack
    public Stack btStackBackward = new Stack();
    public Stack btStack = new Stack();




// Initialize the flight database.
public void setup()
{
    ConnectToDatabase connection= new ConnectToDatabase();
    java.sql.PreparedStatement statement=null;
    ResultSet result=null;

    try{
              statement = connection.getConnection().prepareStatement("SELECT * FROM `grafstatii`");
              result = statement.executeQuery();
              while (result.next()) {
              String from=result.getString(2);
              String to=result.getString(3);
              TraseuInfo ti=new TraseuInfo(from,to);
              addTraseu(ti);
            }


        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }finally
    {
        try
        {
            if (result  != null)
                result.close();
            if (statement  != null)
                statement.close();
            if (connection  != null)
                connection.close();
        }
        catch (SQLException e)
        {
            // ignore
        }
    }


}
// Put flights into the database.
void addTraseu(TraseuInfo ti)
{

    trasee.add(ti);
}

public ArrayList<String> route(String to)
{
    ArrayList<String> statii=new ArrayList<String>();
    String numeStF=null;
    String numeStT=null;
    Stack rev = new Stack();
    double dist = 0;
    TraseuInfo ti;
    int num = btStack.size();
    // Reverse the stack to display route.
    for(int i=0; i < num; i++)
    rev.push(btStack.pop());

    System.out.print("De la statia ");
    for(int i=0; i < num; i++)
    {
    ti = (TraseuInfo) rev.pop();

    ConnectToDatabase connection= new ConnectToDatabase();
    java.sql.PreparedStatement statement1=null;
    java.sql.PreparedStatement statement2=null;
    ResultSet result1=null;
    ResultSet result2=null;


    try{
              statement1 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `id_statie` LIKE "+ti.IDfrom+"");
              statement2 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `id_statie` LIKE "+ti.IDto+"");
              result1 = statement1.executeQuery();
              result2 = statement2.executeQuery();
              while (result1.next()) {
              numeStF=result1.getString(2);

            }
              while (result2.next()) {
              numeStT=result2.getString(2);

            }


        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }finally
        {
        try
        {
            if (result1  != null)
                result1.close();
            if (statement1  != null)
                statement1.close();
             if (result2  != null)
                result2.close();
            if (statement2  != null)
                statement2.close();
            if (connection  != null)
                connection.close();
        }
        catch (SQLException e)
        {
            // ignore
        }
        }


    System.out.print(numeStF + " la statia ");
    statii.add(numeStF);
    dist += ti.distance;
    }
    System.out.println(numeStT);

    statii.add(numeStT);
    System.out.printf("Distanta parcursa este %.2f km" , dist/1000 );
    System.out.println();

    return statii;
}
public double match(String from, String to)
{
   for(int i=trasee.size()-1; i>=0; i--)
   {
   if(trasee.get(i).IDfrom.equals(from) && trasee.get(i).IDto.equals(to) && !trasee.get(i).skip)
   {
      trasee.get(i).skip = true; // prevent reuse
      return trasee.get(i).distance;
   }
   }
        return 0; // not found
}
// Given from, find any connection.
TraseuInfo find(String from)
{

   for(int i=0; i < trasee.size(); i++)
   {
      if(trasee.get(i).IDfrom.equals(from) && !trasee.get(i).skip)
      {
           TraseuInfo ti = new TraseuInfo(trasee.get(i).IDfrom,trasee.get(i).IDto);
           trasee.get(i).skip = true; // prevent reuse
           return ti;
      }
   }
return null;
}

// Determine if there is a route between from and to.
public void isRouteForward(String from, String to)
{
    double dist;
    TraseuInfo ti;
    // See if at destination.
    dist = match(from, to);
    if(dist != 0) {
    btStackForward.push(new TraseuInfo(from, to));
    return;
}
// Try another connection.
   ti = find(from);
   if(ti != null) {
     btStackForward.push(new TraseuInfo(from, to));
     isRouteForward(ti.IDto, to);
   }
    else if(btStackForward.size() > 0) {
    // Backtrack and try another connection.
    ti = (TraseuInfo) btStackForward.pop();
    isRouteForward(ti.IDfrom, ti.IDto);
}
}

public void isRouteBackward(String to, String from)
{
    double dist;
    TraseuInfo ti;
    // See if at destination.
    dist = match(to, from);
    if(dist != 0) {
    btStackBackward.push(new TraseuInfo(to, from));
    return;
}
// Try another connection.
   ti = find(to);
   if(ti != null) {
     btStackBackward.push(new TraseuInfo(to, from));
     isRouteBackward(ti.IDfrom, from);
   }
    else if(btStackBackward.size() > 0) {
    // Backtrack and try another connection.
    ti = (TraseuInfo) btStackBackward.pop();
    isRouteBackward(ti.IDto, ti.IDfrom);
}
    }
public void isRoute(String from,String to){



    isRouteForward(from,to);
    isRouteBackward(to,from);

    int i=0;

    Stack stack1 = new Stack();
    Stack stack2 = new Stack();
    Stack btStackk = new Stack();



 


   while(!btStackForward.isEmpty()&&!btStackBackward.isEmpty())
    {

        stack1.push(btStackForward.pop());
        stack2.push(btStackBackward.pop());
    }
    //else
    {
    btStackk.addAll(stack1);
    btStackk.addAll(stack2);
        }

    btStack.addAll(btStackForward);


}

}
